<template>
  <div class="list">
    <BubbleList :list="bubbleItems" max-height="" ref="bubbleListRef">
      <!-- 自定义头像 -->
      <template #avatar="{ item }">
        <div class="avatar-wrapper">
          <img :src="item.role === 'ai' ? avartAi : avatar" alt="avatar" />
        </div>
      </template>

      <!-- 自定义头部 -->
      <template #header="{ item }">
        <div class="header-wrapper">
          <div class="header-name">
            {{ item.role === "ai" ? "王昕说 🍧" : "🧁 用户" }}
          </div>
        </div>
      </template>

      <!-- 自定义气泡内容 -->
      <template #content="{ item }">
        <div class="content-wrapper">
          <div class="content-text">
            <span v-if="item.role === 'user'">{{ item.content }}</span>
            <span v-else-if="item.role === 'ai' && item.typing">{{ item.content }}</span>
            <Typewriter v-else :content="item.content" is-markdown typing />
          </div>
        </div>
      </template>
    </BubbleList>
  </div>
  <div class="qa_input">
    <Sender v-model="senderValue" clearable @submit="handleSubmit" :loading="senderLoading" />
  </div>
</template>
<script setup>
import { ref, onMounted } from "vue";
import { ElMessage } from "element-plus";
import { v4 as uuidv4 } from "uuid";
import axios from "axios";

//对话列表
const bubbleItems = ref([]);

//用户头像
const avatar = ref("https://avatars.githubusercontent.com/u/76239030?v=4");

//AI 头像
const avartAi = ref("https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png");

//输入框内容
const senderValue = ref("");

//发送按钮加载状态
const senderLoading = ref(false);

//ai_user_id
const userId = ref("");

onMounted(() => {
  // 判断本地缓存是否超过一个月;
  isCacheExpired();

  //判断本地有没有ai_user_id 如果有 直接用 没有 生成
  userId.value = localStorage.getItem("ai_user_id") || uuidv4();

  //判断本地是否有聊天记录缓存 如果有 则直接使用 没有 则使用默认
  bubbleItems.value = JSON.parse(localStorage.getItem("ai_chat_history")) || [];
  //如果有缓存 则给每个ai回复的添加一个表示 不要显示历史记录是 启用打字器效果
  bubbleItems.value.forEach((item) => {
    if (item.role === "ai") {
      item.typing = true;
    }
  });
});

//判断本地缓存是否超过一个月函数
const isCacheExpired = () => {
  //判断本地缓存是否超过一个月 超过一个月则清空缓存
  if (localStorage.getItem("ai_last_time")) {
    const lastTime = new Date(localStorage.getItem("ai_last_time"));
    const now = new Date();
    const diff = now - lastTime;
    const oneMonth = 30 * 24 * 60 * 60 * 1000;
    if (diff > oneMonth) {
      localStorage.removeItem("ai_user_id");
      localStorage.removeItem("ai_chat_history");
    }
  } else {
    localStorage.setItem("ai_last_time", new Date());
  }
};

/**
 * 发送内容
 * @param value
 */
function handleSubmit(value) {
  //启用发送按钮加载状态
  senderLoading.value = true;

  //向列表中添加发送内容
  bubbleItems.value.push({
    key: bubbleItems.value.length + 1,
    role: "user",
    placement: "end",
    loading: false,
    isMarkdown: false,
    typing: false,
    content: value,
    noStyle: true, // 如果你不想用默认的气泡样式
  });

  //将聊天记录添加到本地缓存
  localStorage.setItem("ai_chat_history", JSON.stringify(bubbleItems.value));

  ElMessage.success(`发送成功`);

  //添加一条ai回复空记录
  bubbleItems.value.push({
    key: bubbleItems.value.length + 1,
    role: "ai",
    placement: "start",
    loading: true,
    isMarkdown: true,
    typing: false,
    content: "",
    noStyle: true, // 如果你不想用默认的气泡样式
  });

  //开始sse请求
  startSSE(value);
}

/**
 * sse请求
 * @param value 输入内容
 */
const startSSE = async (value) => {
  try {
    //设置请求头
    const res = await axios.post(
      "https://api.coze.cn/v3/chat",
      {
        bot_id: "7549065741065125934",
        user_id: "123456789",
        stream: true,
        additional_messages: [
          {
            content: value,
            content_type: "text",
            role: "user",
            type: "question",
          },
        ],
        parameters: {},
      },
      {
        headers: {
          "Content-Type": "application/json", // 设置请求体格式为 JSON
          Authorization: "Bearer pat_2RlKVlgffUfQOQqYG4t1B4hIg0uFSWheNqkBpl2n2krcp613O9u4dpf9oKS9xj9H",
        },
      }
    );
    let response = res.data;

    // console.log(response);

    const lines = response.split("\n");
    // console.log(lines);

    let messageList = [];

    for (let i = 0; i < lines.length; i++) {
      let line = lines[i];
      if (line.startsWith("event:")) {
        const ev = line.slice(6);
        switch (ev) {
          case "conversation.message.delta":
            messageList.push(lines[i + 1]);
            break;
          case "done":
            break;
        }
      }
    }

    // console.log(messageList);

    if (messageList.length) {
      for (const message of messageList) {
        if (message.startsWith("data:")) {
          const data = message.slice(5);
          if (data.trim()) {
            //把普通字符串转为json对象
            const event = JSON.parse(data);
            if (event.type == "answer") {
              // console.log(event.content);
              bubbleItems.value[bubbleItems.value.length - 1].loading = false;
              bubbleItems.value[bubbleItems.value.length - 1].content = bubbleItems.value[bubbleItems.value.length - 1].content + event.content;
            }
          }
        }
      }
    }

    //结束发送按钮加载状态
    senderLoading.value = false;

    //清空发送框
    senderValue.value = "";

    //将聊天记录添加到本地缓存
    localStorage.setItem("ai_chat_history", JSON.stringify(bubbleItems.value));
  } catch (error) {
    console.error("Error fetching stream:", error);
  }
};
</script>
<style lang="scss" scoped>
.list {
  width: 100%;
  height: calc(100vh - 150px);
  padding: 10px;
}

::v-deep .el-bubble-list {
  height: 100% !important;
}

/**在pc端添加的样式 */
@media screen and (min-width: 768px) {
  ::v-deep .el-bubble-content {
    max-width: 100% !important;
  }
}

.avatar-wrapper {
  width: 40px;
  height: 40px;
  img {
    width: 100%;
    height: 100%;
    border-radius: 50%;
  }
}

.header-wrapper {
  .header-name {
    font-size: 14px;
    color: #979797;
  }
}

.content-wrapper {
  .content-text {
    font-size: 14px;
    color: #333;
    padding: 12px;
    background: linear-gradient(to right, #fdfcfb 0%, #ffd1ab 100%);
    border-radius: 15px;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
  }
}

.footer-wrapper {
  display: flex;
  align-items: center;
  gap: 10px;
  .footer-time {
    font-size: 12px;
    margin-top: 3px;
  }
}

.footer-container {
  :deep(.el-button + .el-button) {
    margin-left: 8px;
  }
}

.loading-container {
  font-size: 14px;
  color: #333;
  padding: 12px;
  background: linear-gradient(to right, #fdfcfb 0%, #ffd1ab 100%);
  border-radius: 15px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.loading-container span {
  display: inline-block;
  margin-left: 8px;
}

.qa_input {
  width: 100%;
  height: 150px;
  padding: 20px 10px;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;

  ::v-deep .el-textarea__inner {
    max-height: 90px !important;
  }
}
</style>
